package com.kzj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kzj.common.MyUserPhoneThreadLocal;
import com.kzj.common.constant.GlobalConstant;
import com.kzj.common.re.Result;
import com.kzj.dao.EquationDao;
import com.kzj.dao.ExercisesDao;
import com.kzj.dao.UserDao;
import com.kzj.domain.Equation;
import com.kzj.domain.Exercises;
import com.kzj.domain.User;
import com.kzj.domain.bp.ExercisesBP;
import com.kzj.domain.vo.LineChartVO;
import com.kzj.domain.vo.ListVO;
import com.kzj.domain.vo.PieVO;
import com.kzj.domain.vo.RankingListVO;
import com.kzj.service.StatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StatisticsServiceImpl implements StatisticsService {
    @Autowired
    ExercisesDao exercisesDao;
    @Autowired
    EquationDao equationDao;
    @Autowired
    UserDao userDao;
    @Override
    public Result pie() {
        String userPhone =MyUserPhoneThreadLocal.getUserPhone();
        Integer addCount=exercisesDao.getCountByTypeAndIsTimingTime(Exercises.ADDITION,userPhone);
        Integer subCount=exercisesDao.getCountByTypeAndIsTimingTime(Exercises.SUBDUCTION,userPhone);
        Integer mixCount=exercisesDao.getCountByTypeAndIsTimingTime(Exercises.MIX,userPhone);
        Integer mulCount=exercisesDao.getCountByTypeAndIsTimingTime(Exercises.MUL,userPhone);
        Integer divCount=exercisesDao.getCountByTypeAndIsTimingTime(Exercises.DIV,userPhone);
        Integer addCount2=exercisesDao.getCountByTypeAndNoTimingTime(Exercises.ADDITION,userPhone);
        Integer subCount2=exercisesDao.getCountByTypeAndNoTimingTime(Exercises.SUBDUCTION,userPhone);
        Integer mixCount2=exercisesDao.getCountByTypeAndNoTimingTime(Exercises.MIX,userPhone);
        Integer mulCount2=exercisesDao.getCountByTypeAndNoTimingTime(Exercises.MUL,userPhone);
        Integer divCount2=exercisesDao.getCountByTypeAndNoTimingTime(Exercises.DIV,userPhone);
        List<PieVO> list=new ArrayList<>();
        int[] value={addCount2,subCount2,mulCount2,divCount2,mixCount2,addCount,subCount,mulCount,divCount,mixCount};
        String[] type={ GlobalConstant.EXERCISES_TYPE_ADD,GlobalConstant.EXERCISES_TYPE_SUB,
                        GlobalConstant.EXERCISES_TYPE_MUL, GlobalConstant.EXERCISES_TYPE_DIV,
                        GlobalConstant.EXERCISES_TYPE_MIX,
                        GlobalConstant.EXERCISES_TYPE_LIMIT_ADD, GlobalConstant.EXERCISES_TYPE_LIMIT_SUB,
                        GlobalConstant.EXERCISES_TYPE_LIMIT_MUL,GlobalConstant.EXERCISES_TYPE_LIMIT_DIV,
                        GlobalConstant.EXERCISES_TYPE_LIMIT_MIX};
        for(int i=0;i<value.length;i++)
        {
            PieVO pieVO = new PieVO();
            pieVO.setValue(value[i]);
            pieVO.setType(type[i]);
            list.add(pieVO);
        }
        return Result.success(list);
    }

    @Override
    public Result lineChart( ) {
        String userPhone = MyUserPhoneThreadLocal.getUserPhone();
        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        Integer num=7;
        LocalDate startDate=now.minusDays(num);
        LineChartVO lineChartVO=new LineChartVO();
        List<String> list=new ArrayList<>();
        list.add(GlobalConstant.EXERCISES_TYPE_ADD);
        list.add(GlobalConstant.EXERCISES_TYPE_SUB);
        list.add(GlobalConstant.EXERCISES_TYPE_MIX);
        list.add(GlobalConstant.EXERCISES_TYPE_LIMIT_ADD);
        list.add(GlobalConstant.EXERCISES_TYPE_LIMIT_SUB);
        list.add(GlobalConstant.EXERCISES_TYPE_LIMIT_MIX);
        lineChartVO.setName(list);
//        List<List<LineChartVO>> listList=new ArrayList<>();
        for(LocalDate IDate=startDate; IDate.isBefore(now);IDate=IDate.plusDays(1))
        {
            Integer addCount=exercisesDao.getCountBYTypeAndIsTimingTimeAndData(Exercises.ADDITION,userPhone, IDate);
            Integer subCount=exercisesDao.getCountBYTypeAndIsTimingTimeAndData(Exercises.SUBDUCTION,userPhone, IDate);
            Integer mixCount=exercisesDao.getCountBYTypeAndIsTimingTimeAndData(Exercises.MIX,userPhone, IDate);
            Integer mulCount=exercisesDao.getCountBYTypeAndIsTimingTimeAndData(Exercises.MUL,userPhone, IDate);
            Integer divCount=exercisesDao.getCountBYTypeAndIsTimingTimeAndData(Exercises.DIV,userPhone, IDate);
            Integer addCount2=exercisesDao.getCountBYTypeAndNoTimingTimeAndData(Exercises.ADDITION,userPhone, IDate);
            Integer subCount2=exercisesDao.getCountBYTypeAndNoTimingTimeAndData(Exercises.SUBDUCTION,userPhone, IDate);
            Integer mixCount2=exercisesDao.getCountBYTypeAndNoTimingTimeAndData(Exercises.MIX,userPhone, IDate);
            Integer mulCount2=exercisesDao.getCountBYTypeAndNoTimingTimeAndData(Exercises.MUL,userPhone, IDate);
            Integer divCount2=exercisesDao.getCountBYTypeAndNoTimingTimeAndData(Exercises.DIV,userPhone, IDate);
            Integer addTureCount=exercisesDao.getTureCountBYTypeAndIsTimingTimeAndData(Exercises.ADDITION,userPhone, IDate);
            Integer subTureCount=exercisesDao.getTureCountBYTypeAndIsTimingTimeAndData(Exercises.SUBDUCTION,userPhone, IDate);
            Integer mixTureCount=exercisesDao.getTureCountBYTypeAndIsTimingTimeAndData(Exercises.MIX,userPhone, IDate);
            Integer mulTureCount=exercisesDao.getTureCountBYTypeAndIsTimingTimeAndData(Exercises.MUL,userPhone, IDate);
            Integer divTureCount=exercisesDao.getTureCountBYTypeAndIsTimingTimeAndData(Exercises.DIV,userPhone, IDate);
            Integer addTureCount2=exercisesDao.getTureCountBYTypeAndNoTimingTimeAndData(Exercises.ADDITION,userPhone, IDate);
            Integer subTureCount2=exercisesDao.getTureCountBYTypeAndNoTimingTimeAndData(Exercises.SUBDUCTION,userPhone, IDate);
            Integer mixTureCount2=exercisesDao.getTureCountBYTypeAndNoTimingTimeAndData(Exercises.MIX,userPhone, IDate);
            Integer mulTureCount2=exercisesDao.getTureCountBYTypeAndNoTimingTimeAndData(Exercises.MUL,userPhone, IDate);
            Integer divTureCount2=exercisesDao.getTureCountBYTypeAndNoTimingTimeAndData(Exercises.DIV,userPhone, IDate);
            lineChartVO.getDate().add(IDate.format(formatter));
            lineChartVO.getAddList().add(addCount2.equals(0)?0:addTureCount2*100/addCount2);
            lineChartVO.getSubList().add(subCount2.equals(0)?0:subTureCount2*100/subCount2);
            lineChartVO.getMixList().add(mixCount2.equals(0)?0:mixTureCount2*100/mixCount2);
            lineChartVO.getMulList().add(mulCount2.equals(0)?0:mulTureCount2*100/mulCount2);
            lineChartVO.getDivList().add(divCount2.equals(0)?0:divTureCount2*100/divCount2);
            lineChartVO.getAddLimitList().add(addCount.equals(0)?0:addTureCount*100/addCount);
            lineChartVO.getSubLimitList().add(subCount.equals(0)?0:subTureCount*100/subCount);
            lineChartVO.getMixLimitList().add(mixCount.equals(0)?0:mixTureCount*100/mixCount);
            lineChartVO.getMulLimitList().add(mulCount.equals(0)?0:mulTureCount*100/mulCount);
            lineChartVO.getDivLimitList().add(divCount.equals(0)?0:divTureCount*100/divCount);
        }
        return Result.success(lineChartVO);
    }

    @Override
    public Result list() {
        String userPhone = MyUserPhoneThreadLocal.getUserPhone();
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm:ss");
        LambdaQueryWrapper<Exercises> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Exercises::getUserPhone,userPhone)
                .eq(Exercises::getCreateType,Exercises.ONLINE);
        List<Exercises> exercises = exercisesDao.selectList(lqw);
        exercises.sort(new Comparator<Exercises>() {
            @Override
            public int compare(Exercises o1, Exercises o2) {
                return o2.getCreateTime().compareTo(o1.getCreateTime());
            }
        });
        List<ListVO> collect=new ArrayList<>();
        for (Exercises item : exercises) {
            ListVO listVO = new ListVO();

            listVO.setDate(item.getCreateTime().format(formatter));
            listVO.setType(ExercisesBP.getTypeAndTimingToString(item));
            if(item.getTimingTime()!=null&&item.getPracticeTime()!=null)
                listVO.setTime(getTimeString(item.getPracticeTime()));
            Equation equation = equationDao.selectOne(new LambdaQueryWrapper<Equation>().eq(Equation::getExercisesId, item.getId()).last("limit 1"));
            if(equation==null||equation.getPracticeCorrectly()==null)
                continue;
            Integer count = equationDao.getCountByExerciseId(item.getId());
            Integer tureCount = equationDao.getTureCountByExerciseId(item.getId());
            listVO.setTotal(count);
            listVO.setTurePercent(count == 0 ? 0 : tureCount * 100 / count);
            listVO.setFalsePercent(100-listVO.getTurePercent());
            collect.add(listVO);
        }
        return Result.success(collect);
    }

    @Override
    public Result rankingList( ) {
        List<User> users=userDao.getAll();
        List<RankingListVO> collect = users.stream().map(item -> {
            Integer total = equationDao.getCountByUserPhone(item.getPhone());
            Integer tureCount = equationDao.getTureCountByUserPhone(item.getPhone());
            RankingListVO rankingListVO = new RankingListVO();
            rankingListVO.setUserName(item.getUsername());
            rankingListVO.setTotal(total);
            rankingListVO.setTurePercent(total == 0 ? 0 : tureCount * 100 / total);
            return rankingListVO;
        }).collect(Collectors.toList());
        collect.sort(new Comparator<RankingListVO>() {
            @Override
            public int compare(RankingListVO o1, RankingListVO o2) {
                return o2.getTotal()-o1.getTotal();
            }
        });
        return Result.success(collect);
    }

    private String getTimeString(Integer seconds)
    {
        long hours = seconds / 3600;
        long minutes = (seconds % 3600) / 60;
        long remainingSeconds = seconds % 60;

        String result = hours + "小时 " + minutes + "分钟 " + remainingSeconds + "秒";

        return result;
    }
}
